#include "mytracer.h"

MyTracer::MyTracer(QCustomPlot *_plot, TracerType _type, QObject *parent)
    : QObject(parent)
    , m_type(_type)
    , m_plot(_plot)
{
    m_visible = true; // 默认可见
    m_tracer = Q_NULLPTR;// 跟踪的点
    m_label = Q_NULLPTR;// 显示的数值
    m_arrow = Q_NULLPTR;// 箭头
    if (m_plot)
    {
        // 共有设置
        initCommonSettings();
        // 根据追踪器类型设置不同的布局和样式
        switch (m_type)
        {
        case XAxisTracer: { initXAxisTracer(); break; }// X轴追踪器设置
        case YAxisTracer: { initYAxisTracer(); break; }// Y轴追踪器设置
//        case MouseTreacer: { break; }// 鼠标追踪器（预留）
        case DataTracer: { initDataTracer(); break; }// 数据追踪器设置
        default:
            break;
        }
        // 设置为不可见
        setVisible(false);
    }
}

// 析构函数，清理资源
MyTracer::~MyTracer()
{
    if(m_plot)
    {
        if (m_tracer)
            m_plot->removeItem(m_tracer);
        if (m_label)
            m_plot->removeItem(m_label);
        if (m_arrow)
            m_plot->removeItem(m_arrow);
    }
}


// 更新位置
void MyTracer::updatePosition(double xValue, double yValue)
{
//    qDebug() << "追踪器是否显示";
    if (!m_visible)
    {
        setVisible(true);
        m_visible = true;
    }

//    qDebug() << "限制y值在坐标轴范围内";

    // 限制y值在坐标轴范围内
    if (yValue > m_plot->yAxis->range().upper)
        yValue = m_plot->yAxis->range().upper;

    // 判断是否超出范围
    {
        QCPRange xRange = m_plot->xAxis->range();
        QCPRange yRange = m_plot->yAxis->range();

        // 判断是否在坐标轴范围内
        bool isVisible = (xValue >= xRange.lower && xValue <= xRange.upper) &&
                        (yValue >= yRange.lower && yValue <= yRange.upper);
        setVisible(isVisible);

//        qDebug() << "xRange: " << xRange.lower << " " << xValue << " " << xRange.upper;
//        qDebug() << "yRange: " << yRange.lower << " " << yValue << " " << yRange.upper;
//        qDebug() << "是否超出:" << isVisible;
    }


    // 根据追踪器类型更新位置和文本
    switch (m_type)
    {
    case XAxisTracer:
    {
        m_tracer->position->setCoords(xValue, 1);
        m_label->position->setCoords(0, 15);
        m_arrow->start->setCoords(0, 15);
        m_arrow->end->setCoords(0, 0);
        setText(QString::number(xValue));
        break;
    }
    case YAxisTracer:
    {
        m_tracer->position->setCoords(0, yValue);
        m_label->position->setCoords(-20, 0);
        setText(QString::number(yValue));
        break;
    }
    case DataTracer:
    {
#if 1
        QCPGraph* graph = m_tracer->graph();
//        const double xPos = m_tracer->position->key();

        // 获取数据集的x范围
        bool hasValidRange;
        QCPRange dataRange = graph->data()->keyRange(hasValidRange, QCP::sdBoth);

        bool inRange = (xValue >= dataRange.lower) && (xValue <= dataRange.upper);

        // 是否显示
        if(!inRange) {
            return;
        }
        setVisible(inRange);
#endif
        m_tracer->setGraphKey(xValue); // 动态更新数据键值（核心操作）
//        m_tracer->position->setCoords(xValue, yValue);
        m_label->position->setCoords(20, 0);
        setText(QString("x:%1,y:%2").arg(xValue).arg(yValue));
        break;
    }
    default:
        break;
    }
}

// 设置画笔
void MyTracer::setPen(const QPen &pen)
{
    if(m_tracer)
        m_tracer->setPen(pen);
    if(m_arrow)
        m_arrow->setPen(pen);
}
// 设置刷子
void MyTracer::setBrush(const QBrush &brush)
{
    if(m_tracer)
        m_tracer->setBrush(brush);
}
// 设置文本
void MyTracer::setText(const QString &text)
{
    if(m_label)
        m_label->setText(text);
}
// 设置标签画笔
void MyTracer::setLabelPen(const QPen &pen)
{
    if(m_label)
    {
        m_label->setPen(pen);
        m_label->setBrush(Qt::NoBrush);
        m_label->setColor(pen.color());
    }
}
// 设置可见性
void MyTracer::setVisible(bool vis)
{
    m_visible = vis;
    if(m_tracer)
        m_tracer->setVisible(m_visible);
    if(m_label)
        m_label->setVisible(m_visible);
    if(m_arrow)
        m_arrow->setVisible(m_visible);
}
// 设置绑定Graph
void MyTracer::setGraph(QCPGraph *graph)
{
    if(graph) {
        m_tracer->setGraph(graph);
        m_tracer->position->setType(QCPItemPosition::ptPlotCoords); // 保持数据坐标模式
    }
}

void MyTracer::initCommonSettings()
{
    // 设置默认颜色、画笔和刷子
    QColor clrDefault(Qt::red);
    QBrush brushDefault(Qt::NoBrush);
    QPen penDefault(clrDefault);
    penDefault.setWidthF(0.5);

    // 创建追踪点
    m_tracer = new QCPItemTracer(m_plot);
    m_tracer->setStyle(QCPItemTracer::tsCircle);
    m_tracer->setPen(penDefault);
    m_tracer->setBrush(brushDefault);


    // 创建标签
    m_label = new QCPItemText(m_plot);
    m_label->setLayer("overlay");
    m_label->setClipToAxisRect(false);
    m_label->setPadding(QMargins(5, 5, 5, 5));
    m_label->setBrush(brushDefault);
    m_label->setPen(penDefault);
    m_label->position->setParentAnchor(m_tracer->position);
    m_label->setFont(QFont("Arial", 8));
    m_label->setColor(clrDefault);
    m_label->setText("");

    // 创建箭头
    m_arrow = new QCPItemLine(m_plot);
    QPen  arrowPen(clrDefault, 1);
    m_arrow->setPen(penDefault);
    m_arrow->setLayer("overlay");
    m_arrow->setClipToAxisRect(false);
    m_arrow->setHead(QCPLineEnding::esDiamond);//设置头部为箭头形状
}

void MyTracer::initXAxisTracer()
{
    m_tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
    m_tracer->position->setTypeY(QCPItemPosition::ptAxisRectRatio);
    m_tracer->setSize(7);
    m_label->setPositionAlignment(Qt::AlignTop | Qt::AlignHCenter);

    m_arrow->end->setParentAnchor(m_tracer->position);
    m_arrow->start->setParentAnchor(m_arrow->end);
    m_arrow->start->setCoords(0, 20);//偏移量
}

void MyTracer::initYAxisTracer()
{
    m_tracer->position->setTypeX(QCPItemPosition::ptAxisRectRatio);
    m_tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
    m_tracer->setSize(7);
    m_label->setPositionAlignment(Qt::AlignRight | Qt::AlignHCenter);

    m_arrow->end->setParentAnchor(m_tracer->position);
    m_arrow->start->setParentAnchor(m_label->position);
    m_arrow->start->setCoords(-20, 0);//偏移量
}

void MyTracer::initDataTracer()
{
    m_tracer->position->setTypeX(QCPItemPosition::ptPlotCoords);
    m_tracer->position->setTypeY(QCPItemPosition::ptPlotCoords);
    m_tracer->setSize(5);

    m_label->setPositionAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    m_arrow->end->setParentAnchor(m_tracer->position);
    m_arrow->start->setParentAnchor(m_arrow->end);
    m_arrow->start->setCoords(20, 0);
}



// 构造函数，初始化直线追踪器
MyTraceLine::MyTraceLine(QCustomPlot *_plot, MyTraceLine::LineType _type, QObject *parent)
    : QObject(parent)
    , m_type(_type)
    , m_plot(_plot)
{
    m_lineV = Q_NULLPTR;
    m_lineH = Q_NULLPTR;
    initLine();
}
// 析构函数，清理资源
MyTraceLine::~MyTraceLine()
{
    if(m_plot)
    {
        if (m_lineV)
            m_plot->removeItem(m_lineV);
        if (m_lineH)
            m_plot->removeItem(m_lineH);
    }
}
// 初始化直线
void MyTraceLine::initLine()
{
    if(m_plot)
    {
        QPen linesPen(Qt::red, 1, Qt::DashLine);

        if(VerticalLine == m_type || Both == m_type)
        {
            m_lineV = new QCPItemStraightLine(m_plot);
            m_lineV->setLayer("overlay");
            m_lineV->setPen(linesPen);
            m_lineV->setClipToAxisRect(true);
            m_lineV->point1->setCoords(0, 0);
            m_lineV->point2->setCoords(0, 0);
        }

        if(HorizonLine == m_type || Both == m_type)
        {
            m_lineH = new QCPItemStraightLine(m_plot);
            m_lineH->setLayer("overlay");
            m_lineH->setPen(linesPen);
            m_lineH->setClipToAxisRect(true);
            m_lineH->point1->setCoords(0, 0);
            m_lineH->point2->setCoords(0, 0);
        }
    }
}
// 更新直线位置
void MyTraceLine::updatePosition(double xValue, double yValue)
{
    if(VerticalLine == m_type || Both == m_type)
    {
        if(m_lineV)
        {
            // 设置垂直线的两个端点
            m_lineV->point1->setCoords(xValue, m_plot->yAxis->range().lower);
            m_lineV->point2->setCoords(xValue, m_plot->yAxis->range().upper);
        }
    }

    if(HorizonLine == m_type || Both == m_type)
    {
        if(m_lineH)
        {
            // 设置水平线的两个端点
            m_lineH->point1->setCoords(m_plot->xAxis->range().lower, yValue);
            m_lineH->point2->setCoords(m_plot->xAxis->range().upper, yValue);
        }
    }
}
// 设置可见性
void MyTraceLine::setVisible(bool vis)
{
    if(m_lineV)
        m_lineV->setVisible(vis);
    if(m_lineH)
        m_lineH->setVisible(vis);
}
